{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "hUkBRdY8ndhZ",
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "from matplotlib.pyplot import imshow\n",
    "import matplotlib.cm as cm\n",
    "import matplotlib.pylab as plt\n",
    "from keras.preprocessing.image import ImageDataGenerator\n",
    "import numpy as np\n",
    "import PIL\n",
    "from PIL import ImageFilter\n",
    "import cv2\n",
    "import itertools\n",
    "import random\n",
    "import keras\n",
    "import imutils\n",
    "from imutils import paths\n",
    "import os\n",
    "from keras import optimizers\n",
    "from keras.preprocessing.image import img_to_array\n",
    "from sklearn.model_selection import train_test_split\n",
    "from keras.utils import to_categorical\n",
    "from keras import callbacks\n",
    "from keras.models import Sequential\n",
    "from keras.layers.normalization import BatchNormalization\n",
    "from keras.layers import Dense, Dropout, Flatten\n",
    "from keras.layers import Conv2D, MaxPooling2D , UpSampling2D ,Conv2DTranspose\n",
    "from keras import backend as K\n",
    "\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "JHEynQv2ndhn"
   },
   "outputs": [],
   "source": [
    "def pil_image(img_path):\n",
    "    pil_im =PIL.Image.open(img_path).convert('L')\n",
    "    pil_im=pil_im.resize((105,105))\n",
    "    #imshow(np.asarray(pil_im))\n",
    "    return pil_im"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "1hbTCU2qndht"
   },
   "source": [
    "# Augumentation Steps \n",
    "1) Noise\n",
    "2) Blur\n",
    "3) Perpective Rotation\n",
    "4) Shading\n",
    "5) Variable Character Spacing\n",
    "6) Variable Aspect Ratio"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "MLCHbBKsndhv"
   },
   "outputs": [],
   "source": [
    "def noise_image(pil_im):\n",
    "    # Adding Noise to image\n",
    "    img_array = np.asarray(pil_im)\n",
    "    mean = 0.0   # some constant\n",
    "    std = 5   # some constant (standard deviation)\n",
    "    noisy_img = img_array + np.random.normal(mean, std, img_array.shape)\n",
    "    noisy_img_clipped = np.clip(noisy_img, 0, 255)\n",
    "    noise_img = PIL.Image.fromarray(np.uint8(noisy_img_clipped)) # output\n",
    "    #imshow((noisy_img_clipped ).astype(np.uint8))\n",
    "    noise_img=noise_img.resize((105,105))\n",
    "    return noise_img"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "5TPvDBV5ndh2"
   },
   "outputs": [],
   "source": [
    "def blur_image(pil_im):\n",
    "    #Adding Blur to image \n",
    "    blur_img = pil_im.filter(ImageFilter.GaussianBlur(radius=3)) # ouput\n",
    "    #imshow(blur_img)\n",
    "    blur_img=blur_img.resize((105,105))\n",
    "    return blur_img"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "CIDSvv7Qndh6"
   },
   "outputs": [],
   "source": [
    "def affine_rotation(img):\n",
    "    \n",
    "    #img=cv2.imread(img_path,0)\n",
    "    rows, columns = img.shape\n",
    "\n",
    "    point1 = np.float32([[10, 10], [30, 10], [10, 30]])\n",
    "    point2 = np.float32([[20, 15], [40, 10], [20, 40]])\n",
    "\n",
    "    A = cv2.getAffineTransform(point1, point2)\n",
    "\n",
    "    output = cv2.warpAffine(img, A, (columns, rows))\n",
    "    affine_img = PIL.Image.fromarray(np.uint8(output)) # affine rotated output\n",
    "    #imshow(output)\n",
    "    affine_img=affine_img.resize((105,105))\n",
    "    return affine_img\n",
    "   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "VCy6ReUNndh_"
   },
   "outputs": [],
   "source": [
    "def gradient_fill(image):\n",
    "    #image=cv2.imread(img_path,0)\n",
    "    laplacian = cv2.Laplacian(image,cv2.CV_64F)\n",
    "    laplacian = cv2.resize(laplacian, (105, 105))\n",
    "    return laplacian"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "OBLjVHT9ndiF"
   },
   "source": [
    "## Preparing Dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "6hc1RAaVndiI"
   },
   "outputs": [],
   "source": [
    "data_path = \"font_patch/\"\n",
    "data=[]\n",
    "labels=[]\n",
    "imagePaths = sorted(list(paths.list_images(data_path)))\n",
    "random.seed(42)\n",
    "random.shuffle(imagePaths)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "HYYzr_c1ndiN"
   },
   "outputs": [],
   "source": [
    "def conv_label(label):\n",
    "    if label == 'Lato':\n",
    "        return 0\n",
    "    elif label == 'Raleway':\n",
    "        return 1\n",
    "    elif label == 'Roboto':\n",
    "        return 2\n",
    "    elif label == 'Sansation':\n",
    "        return 3\n",
    "    elif label == 'Walkway':\n",
    "        return 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "L5emmKqjd-3Q"
   },
   "outputs": [],
   "source": [
    "augument=[\"blur\",\"noise\",\"affine\",\"gradient\"]\n",
    "a=itertools.combinations(augument, 4)\n",
    "\n",
    "for i in list(a): \n",
    "    print(list(i))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "PIc22kLf4SAP"
   },
   "outputs": [],
   "source": [
    "counter=0\n",
    "for imagePath in imagePaths:\n",
    "    label = imagePath.split(os.path.sep)[-2]\n",
    "    label = conv_label(label)\n",
    "    pil_img = pil_image(imagePath)\n",
    "    #imshow(pil_img)\n",
    "    \n",
    "    # Adding original image\n",
    "    org_img = img_to_array(pil_img)\n",
    "    #print(org_img.shape)\n",
    "    data.append(org_img)\n",
    "    labels.append(label)\n",
    "    \n",
    "    augument=[\"noise\",\"blur\",\"affine\",\"gradient\"]\n",
    "    for l in range(0,len(augument)):\n",
    "    \n",
    "        a=itertools.combinations(augument, l+1)\n",
    "\n",
    "        for i in list(a): \n",
    "            combinations=list(i)\n",
    "            print(len(combinations))\n",
    "            temp_img = pil_img\n",
    "            for j in combinations:\n",
    "            \n",
    "                if j == 'noise':\n",
    "                    # Adding Noise image\n",
    "                    temp_img = noise_image(temp_img)\n",
    "                    \n",
    "                elif j == 'blur':\n",
    "                    # Adding Blur image\n",
    "                    temp_img = blur_image(temp_img)\n",
    "                    #imshow(blur_img)\n",
    "                    \n",
    "    \n",
    "                elif j == 'affine':\n",
    "                    open_cv_affine = np.array(pil_img)\n",
    "                    # Adding affine rotation image\n",
    "                    temp_img = affine_rotation(open_cv_affine)\n",
    "\n",
    "                elif j == 'gradient':\n",
    "                    open_cv_gradient = np.array(pil_img)\n",
    "                    # Adding gradient image\n",
    "                    temp_img = gradient_fill(open_cv_gradient)\n",
    "  \n",
    "            temp_img = img_to_array(temp_img)\n",
    "            data.append(temp_img)\n",
    "            labels.append(label)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 34
    },
    "colab_type": "code",
    "id": "cFpIsgdHndit",
    "outputId": "084a49bf-ee2d-4067-cbde-90d9b42bd8c6"
   },
   "outputs": [],
   "source": [
    "data = np.asarray(data, dtype=\"float\") / 255.0\n",
    "labels = np.array(labels)\n",
    "print(\"Success\")\n",
    "# partition the data into training and testing splits using 75% of\n",
    "# the data for training and the remaining 25% for testing\n",
    "(trainX, testX, trainY, testY) = train_test_split(data,\n",
    "\tlabels, test_size=0.25, random_state=42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "1NQr6OCQ_3qO"
   },
   "outputs": [],
   "source": [
    "# convert the labels from integers to vectors\n",
    "trainY = to_categorical(trainY, num_classes=5)\n",
    "testY = to_categorical(testY, num_classes=5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "9omeq7fqryGW"
   },
   "outputs": [],
   "source": [
    "aug = ImageDataGenerator(rotation_range=30, width_shift_range=0.1,height_shift_range=0.1, shear_range=0.2, zoom_range=0.2,horizontal_flip=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "-vWihISP8kHV"
   },
   "outputs": [],
   "source": [
    "K.set_image_dim_ordering('tf')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "DpDdwzQguqWR"
   },
   "outputs": [],
   "source": [
    " def create_model():\n",
    "  model=Sequential()\n",
    "\n",
    "  # Cu Layers \n",
    "  model.add(Conv2D(64, kernel_size=(48, 48), activation='relu', input_shape=(105,105,1)))\n",
    "  model.add(BatchNormalization())\n",
    "  model.add(MaxPooling2D(pool_size=(2, 2)))\n",
    "\n",
    "  model.add(Conv2D(128, kernel_size=(24, 24), activation='relu'))\n",
    "  model.add(BatchNormalization())\n",
    "  model.add(MaxPooling2D(pool_size=(2, 2)))\n",
    "\n",
    "  model.add(Conv2DTranspose(128, (24,24), strides = (2,2), activation = 'relu', padding='same', kernel_initializer='uniform'))\n",
    "  model.add(UpSampling2D(size=(2, 2)))\n",
    "\n",
    "  model.add(Conv2DTranspose(64, (12,12), strides = (2,2), activation = 'relu', padding='same', kernel_initializer='uniform'))\n",
    "  model.add(UpSampling2D(size=(2, 2)))\n",
    "\n",
    "  #Cs Layers\n",
    "  model.add(Conv2D(256, kernel_size=(12, 12), activation='relu'))\n",
    "\n",
    "  model.add(Conv2D(256, kernel_size=(12, 12), activation='relu'))\n",
    "\n",
    "  model.add(Conv2D(256, kernel_size=(12, 12), activation='relu'))\n",
    "\n",
    "  model.add(Flatten())\n",
    "\n",
    "  model.add(Dense(4096, activation='relu'))\n",
    "\n",
    "  model.add(Dropout(0.5))\n",
    "\n",
    "  model.add(Dense(4096,activation='relu'))\n",
    "\n",
    "  model.add(Dropout(0.5))\n",
    "\n",
    "  model.add(Dense(2383,activation='relu'))\n",
    "\n",
    "  model.add(Dense(5, activation='softmax'))\n",
    " \n",
    "  return model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "LSUkpdoI2J-M"
   },
   "outputs": [],
   "source": [
    "batch_size = 128\n",
    "epochs = 50\n",
    "model= create_model()\n",
    "sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)\n",
    "model.compile(loss='mean_squared_error', optimizer=sgd, metrics=['accuracy'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "IH8DclwlLkOw"
   },
   "outputs": [],
   "source": [
    "early_stopping=callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=10, verbose=0, mode='min')\n",
    "\n",
    "filepath=\"top_model.h5\"\n",
    "\n",
    "checkpoint = callbacks.ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=True, mode='min')\n",
    "\n",
    "callbacks_list = [early_stopping,checkpoint]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "ZfjlSwNt73XO"
   },
   "outputs": [],
   "source": [
    "model.fit(trainX, trainY,shuffle=True,\n",
    "          batch_size=batch_size,\n",
    "          epochs=epochs,\n",
    "          verbose=1,\n",
    "          validation_data=(testX, testY),callbacks=callbacks_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 52
    },
    "colab_type": "code",
    "id": "QLtRqPzhLOUF",
    "outputId": "7de4cd06-136d-424b-dd2d-6d1d85487384"
   },
   "outputs": [],
   "source": [
    "score = model.evaluate(testX, testY, verbose=0)\n",
    "print('Test loss:', score[0])\n",
    "print('Test accuracy:', score[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 34
    },
    "colab_type": "code",
    "id": "9oDaZS8LuWem",
    "outputId": "c308968b-442f-49da-a69e-1a87bdb1cf27"
   },
   "outputs": [],
   "source": [
    "from keras.models import load_model\n",
    "model = load_model('top_model.h5')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 52
    },
    "colab_type": "code",
    "id": "ltfB09zptlNN",
    "outputId": "e023e99b-eb5a-449a-e08f-b124b3f7f284"
   },
   "outputs": [],
   "source": [
    "score = model.evaluate(testX, testY, verbose=0)\n",
    "print('Test loss:', score[0])\n",
    "print('Test accuracy:', score[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "ov6w2Kmdv4dV"
   },
   "outputs": [],
   "source": [
    "img_path=\"sample.jpg\"\n",
    "pil_im =PIL.Image.open(img_path).convert('L')\n",
    "pil_im=blur_img(pil_im)\n",
    "org_img = img_to_array(pil_im)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "jN4su5FX3MzC"
   },
   "outputs": [],
   "source": [
    "def rev_conv_label(label):\n",
    "    if label == 0 :\n",
    "        return 'Lato'\n",
    "    elif label == 1:\n",
    "        return 'Raleway'\n",
    "    elif label == 2 :\n",
    "        return 'Roboto'\n",
    "    elif label == 3 :\n",
    "        return 'Sansation'\n",
    "    elif label == 4:\n",
    "        return 'Walkway'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "q1yBSPTh0ooD"
   },
   "outputs": [],
   "source": [
    "data=[]\n",
    "data.append(org_img)\n",
    "data = np.asarray(data, dtype=\"float\") / 255.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "JR2YCKaaznhT"
   },
   "outputs": [],
   "source": [
    "y = model.predict_classes(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 268
    },
    "colab_type": "code",
    "id": "SQjS-Iv80iLc",
    "outputId": "75bc8aff-55d9-4675-bd36-96070ecfcf49"
   },
   "outputs": [],
   "source": [
    "label = rev_conv_label(int(y[0]))\n",
    "fig, ax = plt.subplots(1)\n",
    "ax.imshow(pil_im, interpolation='nearest', cmap=cm.gray)\n",
    "ax.text(5, 5, label , bbox={'facecolor': 'white', 'pad': 10})\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "collapsed_sections": [],
   "name": "Font_Detect_Updated v1.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "pook",
   "language": "python",
   "name": "pook"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
